package com.fzz.netty.study.ws.global;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import io.netty.channel.Channel;
import io.netty.channel.ChannelId;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * channel 管理
 *
 * @author Administrator
 */
public class ChannelSupervise {
    /**
     * 所有的通道
     */
    private static ChannelGroup GlobalGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    /**
     * channel-->userId-module集合
     */
    private static ConcurrentMap<ChannelId, String> channelUserMap = new ConcurrentHashMap();
    /**
     * userId-module-->channel集合
     */
    private static ConcurrentMap<String, ChannelId> userChannelMap = new ConcurrentHashMap();
    /**
     * 模块集合
     */
    private static Multimap<String, ChannelId> ModuleMap = Multimaps.synchronizedMultimap(HashMultimap.create());

    /**
     * 添加channel
     *
     * @param channel 通道
     * @author fankai
     * @date 2021/11/2 9:04
     **/
    public static void addChannel(Channel channel) {
        GlobalGroup.add(channel);
    }

    /**
     * 添加channel
     *
     * @param channel 通道
     * @param userId  用户id
     * @param module  模块
     * @param uuid    uuid 随机
     * @author fankai
     * @date 2021/11/2 9:04
     **/
    public static void addChannel(Channel channel, String module, String userId, String uuid) {
        String userModule = String.join("-", module, userId, uuid);
        channelUserMap.put(channel.id(), userModule);
        userChannelMap.put(userModule, channel.id());
        ModuleMap.put(module, channel.id());
    }


    /**
     * 删除channel
     *
     * @param channel 通道
     * @author fankai
     * @date 2021/11/2 9:04
     **/
    public static void removeChannel(Channel channel) {
        GlobalGroup.remove(channel);
        final String userModule = channelUserMap.get(channel.id());
        channelUserMap.remove(channel.id());
        userChannelMap.remove(userModule);
        ModuleMap.remove(userModule.split("-")[0], channel.id());

    }


    /**
     * 向模块群发消息
     *
     * @param tws 消息
     * @author fankai
     * @date 2021/11/2 9:05
     **/
    public static void send2Module(TextWebSocketFrame tws, String module) {
        final Collection<ChannelId> channelIds = ModuleMap.get(module);
        SendChannelMatcher matcher = new SendChannelMatcher(channelIds);
        GlobalGroup.writeAndFlush(tws, matcher);
    }

    /**
     * 向用户发消息
     *
     * @param tws 消息
     * @author fankai
     * @date 2021/11/2 9:05
     **/
    public static void send2User(TextWebSocketFrame tws, String userId) {
        Set<ChannelId> channelIds = new HashSet<>();
        for (Map.Entry<String, ChannelId> entry : userChannelMap.entrySet()) {
            final String[] split = entry.getKey().split("-");
            if (split[1].equals(userId)) {
                channelIds.add(entry.getValue());
            }
        }
        SendChannelMatcher matcher = new SendChannelMatcher(channelIds);
        GlobalGroup.writeAndFlush(tws, matcher);
    }

    /**
     * 向模块用户发消息
     *
     * @param tws 消息
     * @author fankai
     * @date 2021/11/2 9:05
     **/
    public static void send2ModuleUser(TextWebSocketFrame tws, String module, String userId) {
        Set<ChannelId> channelIds = new HashSet<>();
        for (Map.Entry<String, ChannelId> entry : userChannelMap.entrySet()) {
            final String[] split = entry.getKey().split("-");
            if (split[0].equals(module) && split[1].equals(userId)) {
                channelIds.add(entry.getValue());
            }
        }
        SendChannelMatcher matcher = new SendChannelMatcher(channelIds);
        GlobalGroup.writeAndFlush(tws, matcher);
    }

    /**
     * 向所有通道群发消息
     *
     * @param tws 消息
     * @author fankai
     * @date 2021/11/2 9:05
     **/
    public static void send2All(TextWebSocketFrame tws) {
        GlobalGroup.writeAndFlush(tws);
    }
}
